/**
 * 封装ajax
 */
export class Ajax {
    /**
     * 内部ajax对象
     */
    private static xhr: XMLHttpRequest;
    constructor() {

    }

    /**
     * 初始化xhr，不会重复初始化
     */
    private static _init() {
        try {
            this.xhr = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                this.xhr = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e1) {
                this.xhr = new XMLHttpRequest();
            }
        }
    }

    /**
     * post请求
     * @param args 
     */
    public static post(args: AjaxArgs) {
        args.method = METHOD_TYPE.POST;
        this._doAjax(args);
    }

    /**
     * get请求
     * @param args 
     */
    public static get(args: AjaxArgs) {
        args.method = METHOD_TYPE.GET;
        if (!!args.data) {
            let completeParam = Ajax.parseDataToUrl(args);
            args.url = args.url + "?" + completeParam;
        }
        this._doAjax(args);
    }

    /**
     * 将data数据转换为url形式，如id=6&name=zc
     * @param args 
     */
    private static parseDataToUrl(args: AjaxArgs): string {
        let data = args.data;
        let params: string[] = [];
        for (let key in data) {
            params.push(key + "=" + data[key]);
        }
        let completeParam: string = params.join("&");
        return completeParam;
    }

    /**
     * 需要在args中指定method，不指定默认使用get
     * @param args 
     */
    public static ajax(args: AjaxArgs) {
        if (!args.method) {
            args.method = METHOD_TYPE.GET;
        }
        switch (args.method) {
            case METHOD_TYPE.POST:
                this.post(args);
                break;
            case METHOD_TYPE.GET:
                this.get(args);
                break;
            default:
                const exhaustiveCheck: never = args.method;
                break;
        }
    }

    /**
     * 实际进行ajax处理，在数据获取成功时resolve，在数据获取失败时reject
     * @param args 
     */
    private static _doAjax(args: AjaxArgs) {
        if (!this.xhr) this._init();
        this.xhr.open(args.method, args.url, true);
        switch (args.method) {
            case METHOD_TYPE.POST:
                if (!args.jsonPara) {
                    if (!args.data) {
                        /**
                         * 无参post请求
                         */
                        this.xhr.send();
                    } else {
                        /**
                         * body传统方式传参
                         */
                        let completeParam = this.parseDataToUrl(args);
                        this.xhr.send(completeParam);
                    }
                } else {
                    /**
                     * json方式传参
                     */
                    this.xhr.setRequestHeader("Conten-type", "application/json");
                    this.xhr.send(JSON.stringify(args.jsonPara));
                }
                break;
            case METHOD_TYPE.GET:
                this.xhr.send();
                break;
            default:
                const exhaustiveCheck: never = args.method;
                break;
        };
        this.xhr.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                args.resolve(this.responseText);
            } else {
            }
        }
    }
}
export interface AjaxArgs {

    /**
     * 完成回调后解析请求
     */
    resolve: (data: string) => void;

    /**
     * 发生错误发生的回调
     */
    reject: (reson: string) => void;

    /**
     * 如果是get请求，则将请求参数拼接到url上
     */
    url: string,

    /**
     * 请求参数
     */
    data?: { [key: string]: string },

    /**
     * 如果是post请求且jsonPara不为空，则忽略data字段
     */
    jsonPara?: object,

    /**
     * 请求方法，如果使用ajax则需要传递
     */
    method?: METHOD_TYPE,

    /**
     * 返回的类型，返回数据中会根据此字段进行解析，默认text
     */
    responseType?: XMLHttpRequestResponseType
}


export enum METHOD_TYPE {
    POST = "POST",
    GET = "GET"
}